﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using LitJson;
using He.Common;

namespace He.API.WeiXin
{
    public class Oauth
    {
        private string _access_token;
        private int _expires_in;
        private string _refresh_token;
        private string _openid;
        private string _scope;

        /// <summary>
        /// 网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
        /// </summary>
        public string access_token
        {
            get
            {
                return this._access_token;
            }
            set
            {
                this._access_token = value;
            }
        }

        /// <summary>
        /// access_token接口调用凭证超时时间，单位（秒）
        /// </summary>
        public int expires_in
        {
            get
            {
                return this._expires_in;
            }
            set
            {
                this._expires_in = value;
            }
        }

        /// <summary>
        /// 用户刷新access_token
        /// </summary>
        public string refresh_token
        {
            get
            {
                return this._refresh_token;
            }
            set
            {
                this._refresh_token = value;
            }
        }

        /// <summary>
        /// 用户唯一标识，请注意，在未关注公众号时，用户访问公众号的网页，也会产生一个用户和公众号唯一的OpenID
        /// </summary>
        public string openid
        {
            get
            {
                return this._openid;
            }
            set
            {
                this._openid = value;
            }
        }

        /// <summary>
        /// 用户授权的作用域，使用逗号（,）分隔
        /// </summary>
        public string scope
        {
            get
            {
                return this._scope;
            }
            set
            {
                this._scope = value;
            }
        }

        /// <summary>
        /// 跳转到网页授权页面
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="siteUrl"></param>
        /// <param name="showAuthPage"></param>
        public static void ToAuthorize(bool showAuthPage)
        {
            string scope = showAuthPage ? "snsapi_userinfo" : "snsapi_base";
            string redirect_uri = HttpContext.Current.Server.UrlEncode(Config.SiteUrl + Config.webset.web_path + "api/weixin/return_url.aspx");
            string uri = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state=#wechat_redirect", Config.wx_config.appid, redirect_uri, scope);
            HttpContext.Current.Response.Redirect(uri);
        }

        /// <summary>
        /// 获取授权信息
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static Oauth GetOauthInfo(string code)
        {
            string uri = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", Config.wx_config.appid, Config.wx_config.appsecret, code);
            string result = HttpHelper.HttpGet(uri);
            if (result.Contains("error"))
            {
                return null;
            }
            Oauth oauth = JsonMapper.ToObject<Oauth>(result);
            CookieHelper.Set(oauth.access_token, SysKeys.WX_OAUTH_ACCESS_TOKEN_COOKIE_NAME, oauth.expires_in);
            CookieHelper.Set(oauth.refresh_token, SysKeys.WX_OAUTH_REFRESH_TOKEN_COOKIE_NAME, oauth.expires_in);
            CookieHelper.Set(oauth.openid, SysKeys.WX_OAUTH_OPENID_COOKIE_NAME, oauth.expires_in);
            return oauth;
        }

        /// <summary>
        /// 刷新授权信息
        /// </summary>
        /// <param name="_refresh_token"></param>
        /// <returns></returns>
        public static Oauth RefreshOauthInfo(string _refresh_token)
        {
            string uri = string.Format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type=refresh_token&refresh_token={1}", Config.wx_config.appid, _refresh_token);
            string result = HttpHelper.HttpGet(uri);
            if (result.Contains("error"))
            {
                return null;
            }
            Oauth oauth = JsonMapper.ToObject<Oauth>(result);
            CookieHelper.Set(oauth.access_token, SysKeys.WX_OAUTH_ACCESS_TOKEN_COOKIE_NAME, oauth.expires_in);
            CookieHelper.Set(oauth.refresh_token, SysKeys.WX_OAUTH_REFRESH_TOKEN_COOKIE_NAME, oauth.expires_in);
            CookieHelper.Set(oauth.openid, SysKeys.WX_OAUTH_OPENID_COOKIE_NAME, oauth.expires_in);
            return oauth;
        }

        /// <summary>
        /// 拉取用户信息(需scope为 snsapi_userinfo)
        /// </summary>
        /// <param name="_access_token"></param>
        /// <param name="_openid"></param>
        /// <returns></returns>
        public static UserInfo GetUserInfo(string code)
        {
            string _access_token = CookieHelper.Get(SysKeys.WX_OAUTH_ACCESS_TOKEN_COOKIE_NAME);
            string _openid = CookieHelper.Get(SysKeys.WX_OAUTH_OPENID_COOKIE_NAME);
            string _refresh_token = CookieHelper.Get(SysKeys.WX_OAUTH_REFRESH_TOKEN_COOKIE_NAME);

            if (string.IsNullOrEmpty(_access_token))
            {
                //TODO 刷新access_token
                if (!string.IsNullOrEmpty(_refresh_token))
                {
                    Oauth oauth = RefreshOauthInfo(_refresh_token);
                    _access_token = oauth.access_token;
                    _openid = oauth.openid;
                    _refresh_token = oauth.refresh_token;
                }
            }

            if (!TokenIsValid(_access_token, _openid))
            {
                //TODO 重新获取有效的access_token
                Oauth oauth = GetOauthInfo(code);
                _access_token = oauth.access_token;
                _openid = oauth.openid;
                _refresh_token = oauth.refresh_token;
            }

            //TODO 通过access_token拉取用户信息
            string uri = string.Format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN", _access_token, _openid);
            string result = HttpHelper.HttpGet(uri);
            UserInfo info = JsonMapper.ToObject<UserInfo>(result);
            return info;
        }

        /// <summary>
        /// 检验授权凭证（access_token）是否有效
        /// </summary>
        /// <param name="_access_token"></param>
        /// <param name="_openid"></param>
        /// <returns></returns>
        public static bool TokenIsValid(string _access_token, string _openid)
        {
            string uri = string.Format("https://api.weixin.qq.com/sns/auth?access_token={0}&openid={1}", _access_token, _openid);
            string result = HttpHelper.HttpGet(uri);
            Dictionary<string, object> dic = JsonMapper.ToObject<Dictionary<string, object>>(result);
            string errcode = dic["errcode"].ToString();
            if (errcode == "0")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
